<template>
  <div ref="propertyPanel" class="property-panel">
    <el-tabs type="border-card" style="height: calc(100vh - 180px)">
      <el-tab-pane label="消息定义">
        <div style="margin:0px;padding:0px" class="clear">
          <vxe-toolbar perfect>
            <template v-slot:buttons>
              <vxe-button icon="el-icon-plus" status="perfect" size="mini" @click="insertEvent">新增</vxe-button>
              <vxe-button icon="el-icon-remove" status="perfect" size="mini" @click="removeEvent">移除</vxe-button>
              <vxe-button icon="el-icon-check" status="perfect" size="mini" @click="saveEvent">保存</vxe-button>
            </template>
          </vxe-toolbar>
          <vxe-table
            ref="xTable"
            border
            show-overflow
            keep-source
            :data="messages"
            :edit-config="{trigger: 'click', mode: 'cell', showStatus: true}"
          >
            <vxe-table-column width="40px" type="checkbox" />
            <vxe-table-column field="id" title="ID" :edit-render="{name: 'input'}" />
            <vxe-table-column field="name" title="名称" :edit-render="{name: 'input'}" />
          </vxe-table>
        </div>
      </el-tab-pane>
      <el-tab-pane label="基本属性">
        <el-form ref="processForm" :model="process" :rules="processFormRules" label-width="100px" size="small">
          <el-form-item label="流程名称" prop="processName">
            <el-input v-model="process.processName" readonly />
          </el-form-item>
          <el-form-item label="流程代码" prop="key">
            <el-input v-model="process.key" readonly />
          </el-form-item>
        </el-form>
        <el-form ref="modelForm" :model="modelForm" label-width="100px" size="small">
          <el-form-item v-if="element" label="节点定义">
            <el-input v-model="modelForm.id" @input="idChange" />
          </el-form-item>
          <el-form-item v-if="element" label-width="100px" label="节点名称">
            <el-input v-model="modelForm.name" @input="nameChange" />
          </el-form-item>
          <el-form-item v-if="sequenceFlow" label-width="100px" label="分支条件">
            <el-input
              v-model="modelForm.condition"
              type="textarea"
              :rows="4"
              placeholder="请输入表达式"
              @change="changeCondition()"
            />
          </el-form-item>
          <el-form-item v-if="element" label-width="100px" label="表单ID">
            <el-input v-model="modelForm.formKey" @input="formKeyChange" />
          </el-form-item>
          <el-form-item v-if="timerTrigger" label-width="100px" label="定时器">
            <el-input v-model="modelForm.cronexpression" @input="timeCirleChange" />
          </el-form-item>
          <!-- 指定人员 -->
          <el-form-item v-if="messageTrigger" label="消息事件">
            <el-select
              v-model="modelForm.message"
              placeholder="请选择消息"
              @change="(value) => addMessage(value)"
            >
              <el-option
                v-for="item in messages"
                :key="item.id"
                :label="item.name"
                :value="item.id"
              />
            </el-select>
          </el-form-item>
        </el-form>
      </el-tab-pane>
      <el-tab-pane v-if="userTask" label="人员选择">
        <el-form ref="candidate" :model="process" label-width="80px" size="small">
          <!-- 指定人员 -->
          <el-form-item label="分发人">
            <el-select
              v-model="modelForm.assignee"
              placeholder="请选择分发人"
              multiple
              @change="(value) => addUser({assignUsers: value.join(',') || value})"
            >
              <el-option
                v-for="item in users"
                :key="item.Id"
                :label="item.Name"
                :value="item.Id"
              />
            </el-select>
          </el-form-item>
          <!-- 角色 -->
          <el-form-item label="候选角色">
            <el-select
              v-model="modelForm.candidateRoles"
              multiple
              placeholder="请选择角色"
              @change="(value) => addUser({candidateRoles: value.join(',') || value})"
            >
              <el-option
                v-for="item in roles"
                :key="item.Id"
                :label="item.Name"
                :value="item.Id"
              />
            </el-select>
          </el-form-item>
        </el-form>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>
<script>
export default {
  name: 'PropertyPanel',
  props: {
    modeler: {
      type: Object,
      required: true
    },
    rowData: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      activeName: 'first',
      messages: [],
      roles: [],
      modelForm: {
        id: '',
        name: '',
        color: null,
        condition: '',
        cronexpression: '',
        message: '',
        formKey: ''
      },
      process: {
        processName: '',
        key: ''
      },
      processFormRules: {
        category: [{ required: true, message: '请选择分类', trigger: 'blur' }],
        processName: [{ required: true, message: '请输入流程名称', trigger: 'blur' },
          { min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur' }],
        key: [{ required: true, message: '请输入流程key', trigger: 'blur' }]
      },
      element: {},
      users: []
    }
  },
  computed: {
    timerTrigger() {
      if (!this.element) {
        return
      }
      if (this.element.businessObject && this.element.businessObject.eventDefinitions) {
        const arr = this.element.businessObject.eventDefinitions.filter(r => r.$type === 'bpmn:TimerEventDefinition')
        return arr.length > 0
      } else {
        return false
      }
    },
    messageTrigger() {
      if (!this.element) {
        return
      }
      if (this.element.businessObject && this.element.businessObject.eventDefinitions) {
        const arr = this.element.businessObject.eventDefinitions.filter(r => r.$type === 'bpmn:MessageEventDefinition')
        return arr.length > 0
      } else {
        return false
      }
    },
    userTask() {
      if (!this.element) {
        return
      }
      return this.element.type === 'bpmn:UserTask'
    },
    sequenceFlow() {
      if (!this.element) {
        return
      }
      return this.element.type === 'bpmn:SequenceFlow'
    }
    /* messages() {
      const rootElements = this.modeler._definitions.rootElements || []
      const messages = rootElements.filter(r => r.$type === 'bpmn:Message') || []
      messages.forEach((_data, _index) => {
        if (_data.Id && _data.Name) {
          // eslint-disable-next-line vue/no-side-effects-in-computed-properties
          this.messages_arr.push({
            Id: _data.Id,
            Name: _data.Name
          })
        }
      })
      return this.messages_arr
    }*/

  },
  mounted() {
    if (Object.keys(this.rowData).length > 0) {
      this.process = {
        processName: this.rowData.processName,
        key: this.rowData.key
      }
    }
    this.roles = this.rowData.roles
    this.users = this.rowData.users
    this.handleModeler()
  },
  methods: {
    init() {
      this.messages = []
      const rootElements = this.modeler._definitions.rootElements || []
      const messages = rootElements.filter(r => r.$type === 'bpmn:Message') || []
      messages.forEach((_data, _index) => {
        if (_data.id && _data.name) {
          // eslint-disable-next-line vue/no-side-effects-in-computed-properties
          this.messages.push({
            id: _data.id,
            name: _data.name
          })
        }
      })
    },
    addMessage(value) { // messageRef
      this.element.businessObject.eventDefinitions[0].$attrs.messageRef = value
    },
    handleSave() {
      this.$emit('handleCallConfigBack', this.processName)
    },
    handleModeler() {
      // 监听节点选择变化
      this.modeler.on('selection.changed', e => {
        const element = e.newSelection[0]
        this.element = element
        if (element) {
          this.modelForm = {
            ...element.businessObject,
            ...element.businessObject.$attrs
          }
          if (this.modelForm.userType === 'candidateUsers') {
            this.modelForm['candidateUsers'] = this.modelForm['candidateUsers'].split(',') || []
          }
          if (this.element.businessObject && this.element.businessObject.eventDefinitions) {
            const arr = this.element.businessObject.eventDefinitions.filter(r => r.$type === 'bpmn:TimerEventDefinition')
            this.modelForm.cronexpression = arr[0].timeCycle.body
          }
        } else {
          this.modelForm = {}
        }
      })

      //  监听节点属性变化
      this.modeler.on('element.changed', e => {
        const { element } = e
        if (!element) return
        //  新增节点需要更新回属性面板
        if (element.id === this.modelForm.id) {
          this.modelForm.name = element.businessObject.name
          this.modelForm = { ...this.modelForm }
        }
      })
    },
    // 属性面板名称，更新回流程节点
    nameChange(name) {
      if (!this.element) return
      const modeling = this.modeler.get('modeling')
      modeling.updateLabel(this.element, name)
    },
    idChange(id) {
      if (!this.element) return
      const modeling = this.modeler.get('modeling')
      modeling.updateProperties(this.element, { 'id': id })
    },
    formKeyChange(formKey) {
      if (!this.element) return
      const modeling = this.modeler.get('modeling')
      modeling.updateProperties(this.element, { 'formKey': formKey })
    },
    timeCirleChange() {
      const moddle = this.modeler.get('moddle')
      const cirlemodel = moddle.create('bpmn:Expression', { body: this.modelForm.cronexpression })
      this.element.businessObject.eventDefinitions[0].set('timeCycle', cirlemodel)
    },
    changeCondition() {
      const modeling = this.modeler.get('modeling')
      const moddle = this.modeler.get('moddle')
      const expressmodel = moddle.create('bpmn:FormalExpression', {
        body: this.modelForm.condition
      })
      modeling.updateProperties(this.element, { 'condition': this.modelForm.condition })
      modeling.updateProperties(this.element, { 'conditionExpression': expressmodel })
    },
    // 属性面板颜色，更新回流程节点
    colorChange(color) {
      const modeling = this.modeler.get('modeling')
      modeling.setColor(this.element, {
        fill: null,
        stroke: color
      })
      modeling.updateProperties(this.element, { color: color })
    },
    insertEvent() {
      const record = {
        id: '',
        name: ''
      }
      this.$refs.xTable.insert(record).then(({ row }) => {
        this.$refs.xTable.setActiveCell(row, 'sex')
      })
    },
    removeEvent() {
      const selectRecords = this.$refs.xTable.getCheckboxRecords()
      if (selectRecords.length) {
        this.$refs.xTable.removeCheckboxRow()
      } else {
        this.$XModal.message({ message: '请至少选择一条数据', status: 'error' })
      }
    },
    // 任务节点配置人员
    addUser(properties) {
      this.updateProperties(
        properties
      )
    },
    saveEvent() {
      const { insertRecords, updateRecords } = this.$refs.xTable.getRecordset()
      const rootElements = this.modeler._definitions.rootElements || []
      const messages = rootElements.filter(r => r.$type === 'bpmn:Message') || []
      messages.forEach((_data, _index) => {
        rootElements.pop(_data)
      })
      const records = (insertRecords || []).concat(updateRecords || []).concat(this.messages || [])
      const arrNew = new Set(records)
      Array.from(arrNew).forEach((_data, _index) => {
        const moddle = this.modeler.get('moddle')
        const msg = moddle.create('bpmn:Message')
        msg.name = _data.name
        msg.id = _data.id
        rootElements.push(msg)
      })
      this.messages = Array.from(arrNew)
      this.$message({
        message: '操作成功',
        type: 'success',
        duration: 1500
      })
    },
    // 在这里我们封装一个通用的更新节点属性的方法
    updateProperties(properties) {
      const modeling = this.modeler.get('modeling')
      modeling.updateProperties(this.element, properties)
    }
  }
}
</script>

<style lang="scss" scoped>
</style>
